#[cfg(test)]
mod tests {
    #[derive(Debug)]
    struct Y32(i32);
    #[derive(Debug)]
    struct Y16(i16);

    trait Year {
        type A;

        fn diff(&self, other: Self) -> Self;
    }

    impl Year for Y32 {
        type A = i32;
        fn diff(&self, other: Self) -> Self {
            Y32(self.0 - other.0)
        }
    }

    impl Year for Y16 {
        type A = i16;
        fn diff(&self, other: Self) -> Self {
            Self(self.0 - other.0)
        }
    }

    #[derive(Debug)]
    struct M8(u8);
    #[derive(Debug)]
    struct M16(u16);

    trait Month<T> {
        fn diff(&self, other: Self) -> Self;
    }

    impl Month<u8> for M8 {
        fn diff(&self, other: Self) -> Self {
            Self(self.0 - other.0)
        }
    }

    impl Month<u16> for M16 {
        fn diff(&self, other: Self) -> Self {
            Self(self.0 - other.0)
        }
    }

    trait Date<A, B, C> {
        fn compare(&self, other: Self) -> i32;
    }

    struct Dmin(u16, u8, u8);
    struct Dmax(i32, i32, i32);

    impl Dmin {
        fn get_days(&self) -> i32 {
            let days = get_year_month_day_list(self.0);
            days[..(self.1 - 1) as usize].iter().sum::<i32>() + self.2 as i32
        }

        fn get_year_days(&self) -> i32 {
            get_year_days(self.0)
        }
    }

    fn get_year_month_day_list<T>(year: T) -> [i32; 12]
    where
        T: Into<i32> + Copy,
    {
        if is_leap_year(year) {
            [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        } else {
            [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        }
    }

    fn is_leap_year<T>(year: T) -> bool
    where
        T: Into<i32> + Copy, // 允许所有可以转换为 i32 的整数类型
    {
        // 闰年的条件：能被4整除，但不能被100整除，除非同时能被400整除
        (year.into() % 4 == 0) && (year.into() % 100 != 0) || (year.into() % 400 == 0)
    }

    fn get_year_days<T>(year: T) -> i32
    where
        T: Into<i32> + Copy,
    {
        if is_leap_year(year) {
            366
        } else {
            365
        }
    }

    impl Date<u16, u8, u8> for Dmin {
        fn compare(&self, other: Self) -> i32 {
            if self.0 == other.0 && self.1 == other.1 {
                return (self.2 - other.2) as i32;
            }

            let is_bigger = self.0 > other.0 && self.1 > other.1;
            let mut days = 0;
            if is_bigger {
                days += other.get_year_days() - other.get_days();
                for i in other.0 + 1..self.0 {
                    days += get_year_days(i)
                }
                days += self.get_days();
            } else {
                days -= self.get_year_days() - self.get_year_days();
                for i in self.0 + 1..other.0 {
                    days -= get_year_days(i)
                }
                days -= other.get_days();
            }
            days
        }
    }

    impl Date<i32, i32, i32> for Dmax {
        fn compare(&self, other: Self) -> i32 {
            let days = get_year_month_day_list(self.0);
            let sum1: i32 = days[..(self.1 - 1) as usize].iter().sum::<i32>() + self.2 as i32;
            let sum2: i32 = days[..(other.1 - 1) as usize].iter().sum::<i32>() + other.2 as i32;

            sum1 - sum2
        }
    }

    #[test]
    fn test() {
        let y32_1 = Y32(2020);
        let y32_2 = Y32(2011);
        println!("{:?}", y32_1.diff(y32_2));

        let y16_1 = Y16(2020);
        let y16_2 = Y16(2011);
        println!("{:?}", y16_1.diff(y16_2));

        let m16_1 = M16(12);
        let m16_2 = M16(2);
        println!("{:?}", m16_1.diff(m16_2));

        let m8_1 = M8(12);
        let m8_2 = M8(2);
        println!("{:?}", m8_1.diff(m8_2));

        let dmin1 = Dmin(2024, 9, 13);
        let dmin2 = Dmin(2020, 4, 5);
        println!("{}", dmin1.compare(dmin2));
    }

    #[test]
    fn test_get_days() {
        assert_eq!(257, Dmin(2024, 9, 13).get_days());
        assert_eq!(270, get_year_days(2020) - Dmin(2020, 4, 5).get_days());
    }
}
